const FPS = 60;
const BULLET_SPEED = 8;
const ENEMY_SPEED = 3;
const ENEMY_BULLET_SPEED = 5;
const ENEMY_FIRE_INTERVAL = 2000;

Page({
  data: {
    canvasWidth: 320,
    canvasHeight: 540,
    gameStart: false,
    gameOver: false,
    score: 0,
    life: 3,
    playerX: 160,
    bullets: [],
    enemies: [],
    dpr: 1,
    planeImg: null,
    enemyImg: null,
  },

  onReady() {
    this.initCanvas();
  },

  initCanvas() {
    const query = wx.createSelectorQuery();
    query.select('#gameCanvas')
      .fields({ node: true, size: true })
      .exec((res) => {
        if (!res[0] || !res[0].node) {
          console.error('Canvas初始化失败');
          return;
        }

        const canvas = res[0].node;
        const ctx = canvas.getContext('2d');
        const windowInfo = wx.getWindowInfo();
        const dpr = windowInfo.pixelRatio;

        canvas.width = res[0].width * dpr;
        canvas.height = res[0].height * dpr;
        ctx.scale(dpr, dpr);

        this.setData({
          dpr: dpr,
          canvasWidth: res[0].width,
          canvasHeight: res[0].height,
        });

        this.canvas = canvas;
        this.ctx = ctx;

        this.loadImages().then(() => {
          this.drawElements();
        });
      });
  },

  loadImages() {
    return new Promise((resolve) => {
      const planeImg = this.canvas.createImage();
      planeImg.src = '/images/plane.png';
      planeImg.onload = () => {
        this.setData({ planeImg }, resolve);
      };

      const enemyImg = this.canvas.createImage();
      enemyImg.src = '/images/enemy1.png';
      enemyImg.onload = () => {
        this.setData({ enemyImg }, resolve);
      };
    });
  },

  startGame() {
    this.setData({
      gameStart: true,
      gameOver: false,
      score: 0,
      life: 3,
      playerX: 160,
      bullets: [],
      enemies: [],
    }, () => {
      this.gameLoop();
      this.enemyGenerator();
    });
  },

  gameLoop() {
    if (this.data.gameOver || !this.data.gameStart) return;

    this.clearCanvas();
    this.moveBullets();
    this.moveEnemies();
    this.enemyFire();
    this.checkCollisions();
    this.drawElements();

    setTimeout(() => this.gameLoop(), 1000 / FPS);
  },

  enemyGenerator() {
    if (this.data.gameOver) return;

    const newEnemy = {
      x: Math.random() * (this.data.canvasWidth - 30),
      y: -30,
      type: Math.random() > 0.9 ? 2 : 1,
      lastShot: 0
    };

    this.setData({ enemies: [...this.data.enemies, newEnemy] });
    this.enemyGeneratorTimeout = setTimeout(() => this.enemyGenerator(), 1500);
  },

  touchStart(e) {
    this.touchX = e.touches[0].x;
  },

  touchMove(e) {
    const moveX = (e.touches[0].x - this.touchX) / this.data.dpr;
    this.touchX = e.touches[0].x;

    const speedFactor = 2;
    let newX = this.data.playerX + moveX * speedFactor;
    newX = Math.max(15, Math.min(newX, this.data.canvasWidth - 15));
    this.setData({ playerX: newX });
  },

  fireBullet() {
    const newBullets = [...this.data.bullets];
    if (Date.now() - (this.lastShot || 0) > 200) {
      newBullets.push({
        x: this.data.playerX,
        y: this.data.canvasHeight - 60,
        direction: 0 // 玩家子弹方向：向上
      });
      this.lastShot = Date.now();
      this.setData({ bullets: newBullets });
    }
  },

  enemyFire() {
    const now = Date.now();
    const enemies = this.data.enemies.map(enemy => {
      if (now - enemy.lastShot > ENEMY_FIRE_INTERVAL) {
        this.setData({
          bullets: [
            ...this.data.bullets,
            {
              x: enemy.x,
              y: enemy.y + 20,
              direction: 1 // 敌机子弹方向：向下
            }
          ]
        });
        return { ...enemy, lastShot: now };
      }
      return enemy;
    });
    this.setData({ enemies });
  },

  moveBullets() {
    const newBullets = this.data.bullets
      .filter((b) => b.y > -10 && b.y < this.data.canvasHeight + 10)
      .map((b) => ({
        ...b,
        y: b.direction 
          ? b.y + ENEMY_BULLET_SPEED 
          : b.y - BULLET_SPEED
      }));
    this.setData({ bullets: newBullets });
  },

  moveEnemies() {
    this.setData({
      enemies: this.data.enemies
        .filter((e) => e.y < this.data.canvasHeight + 50)
        .map((e) => ({ ...e, y: e.y + ENEMY_SPEED })),
    });
  },

  checkCollisions() {
    // 玩家与敌机碰撞
    this.data.enemies.forEach((enemy) => {
      const playerCenterX = this.data.playerX;
      const playerCenterY = this.data.canvasHeight - 55;
      const enemyCenterX = enemy.x;
      const enemyCenterY = enemy.y;
      
      const distance = Math.sqrt(
        Math.pow(enemyCenterX - playerCenterX, 2) +
        Math.pow(enemyCenterY - playerCenterY, 2)
      );

      if (distance < 35) { // 玩家和敌机的碰撞半径
        this.hitPlayer();
      }
    });

    // 玩家子弹与敌机碰撞
    this.data.bullets
      .filter(b => b.direction === 0)
      .forEach((bullet) => {
        this.data.enemies.forEach((enemy) => {
          const distance = Math.sqrt(
            Math.pow(bullet.x - enemy.x, 2) +
            Math.pow(bullet.y - enemy.y, 2)
          );

          if (distance < 20) { // 子弹和敌机的碰撞半径
            this.setData({
              score: this.data.score + (enemy.type === 2 ? 5 : 1),
              enemies: this.data.enemies.filter((e) => e !== enemy),
              bullets: this.data.bullets.filter((b) => b !== bullet)
            });
          }
        });
      });

    // 敌机子弹与玩家碰撞（新增精确检测）
    this.data.bullets
      .filter(b => b.direction === 1)
      .forEach((bullet) => {
        const playerCenterX = this.data.playerX;
        const playerCenterY = this.data.canvasHeight - 55;
        
        const distance = Math.sqrt(
          Math.pow(bullet.x - playerCenterX, 2) +
          Math.pow(bullet.y - playerCenterY, 2)
        );

        if (distance < 25) { // 综合碰撞半径
          this.hitPlayer();
          this.setData({
            bullets: this.data.bullets.filter((b) => b !== bullet)
          });
        }
      });
  },

  hitPlayer() {
    //this.setData({ gameOver: true });    //此为仅有一条命
    if (this.data.life <= 1) {
      this.setData({ gameOver: true });
    } else {
      this.setData({ life: this.data.life - 1 });
    }
  },

  drawElements() {
    if (this.data.gameOver) return;
    const ctx = this.ctx;

    this.clearCanvas();

    // 绘制玩家
    if (this.data.planeImg) {
      ctx.drawImage(
        this.data.planeImg,
        this.data.playerX - 25,
        this.data.canvasHeight - 80,
        50,
        50
      );
    }

    // 绘制子弹
    this.data.bullets.forEach((b) => {
      ctx.beginPath();
      ctx.fillStyle =  '#ff0000';
      ctx.arc(b.x, b.y, 3, 0, 2 * Math.PI);
      ctx.fill();
    });

    // 绘制敌机
    if (this.data.enemyImg) {
      this.data.enemies.forEach((e) => {
        ctx.drawImage(
          this.data.enemyImg,
          e.x - 15,
          e.y - 15,
          30,
          30
        );
      });
    }
  },

  clearCanvas() {
    this.ctx.clearRect(
      0,
      0,
      this.data.canvasWidth * this.data.dpr,
      this.data.canvasHeight * this.data.dpr
    );
  },

  gameOver() {
    this.setData({ gameOver: true });
    clearTimeout(this.enemyGeneratorTimeout);
  },
});